﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.Windows.Media;
using JiveMessenger.Models;
using GalaSoft.MvvmLight.Command;
using System.Diagnostics;
using System.Windows.Media.Animation;
using JiveMessenger.Helpers;
using JiveMessenger.Settings;
using System.ComponentModel;

namespace JiveMessenger.CustomControls
{
    public class EmoticonClickedEventArgs : EventArgs
    {
        public EmoticonModel Model { get; set; }
        public EmoticonClickedEventArgs(EmoticonModel model)
        {
            this.Model = model;
        }
    }
    public partial class EmoticonControl : UserControl
    {
        public static bool NeedRefresh { get; set; }
        public RelayCommand<EmoticonModel> DeleteCustomEmoticonCommand { get; set; }
        public event EventHandler<EventArgs> BackspaceEvent;
        public event EventHandler<EventArgs> SendMessageEvent;
        public event EventHandler<EmoticonClickedEventArgs> ClickEmoticonEvent;
        private bool isHolding { get; set; }
        public string ClickedEmoticon { get; set; }
        private Thread HoldingThread { get; set; }




        public bool IsTouchSensitive
        {
            get { return (bool)GetValue(IsTouchSensitiveProperty); }
            set { SetValue(IsTouchSensitiveProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsTouchSensitive.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsTouchSensitiveProperty =
            DependencyProperty.Register("IsTouchSensitive", typeof(bool), typeof(EmoticonControl), new PropertyMetadata(false, new PropertyChangedCallback(IsTouchSensitiveProperty_Callback)));




        //public ObservableCollection<EmoticonModel> RecentlyUsedEmoticons { get; set; }



        public ObservableCollection<EmoticonModel> RecentlyUsedEmoticons
        {
            get { return (ObservableCollection<EmoticonModel>)GetValue(RecentlyUsedEmoticonsProperty); }
            set { SetValue(RecentlyUsedEmoticonsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RecentlyUsedEmoticons.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RecentlyUsedEmoticonsProperty =
            DependencyProperty.Register("RecentlyUsedEmoticons", typeof(ObservableCollection<EmoticonModel>), typeof(EmoticonControl), new PropertyMetadata(null));


        public int EmoticonPivotIndex
        {
            get { return (int)GetValue(EmoticonPivotIndexProperty); }
            set { SetValue(EmoticonPivotIndexProperty, value); }
        }

        // Using a DependencyProperty as the backing store for EmoticonPivotIndex.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty EmoticonPivotIndexProperty =
            DependencyProperty.Register("EmoticonPivotIndex", typeof(int), typeof(EmoticonControl), new PropertyMetadata(0));




        public ObservableCollection<EmoticonModel> CustomEmoticons
        {
            get { return (ObservableCollection<EmoticonModel>)GetValue(CustomEmoticonsProperty); }
            set { SetValue(CustomEmoticonsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CustomEmoticons.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CustomEmoticonsProperty =
            DependencyProperty.Register("CustomEmoticons", typeof(ObservableCollection<EmoticonModel>), typeof(EmoticonControl), new PropertyMetadata(null));



        public ObservableCollection<EmoticonModel> DefaultEmoticons
        {
            get { return (ObservableCollection<EmoticonModel>)GetValue(DefaultEmoticonsProperty); }
            set
            {
                SetValue(DefaultEmoticonsProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for DefaultEmoticons.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DefaultEmoticonsProperty =
            DependencyProperty.Register("DefaultEmoticons", typeof(ObservableCollection<EmoticonModel>), typeof(EmoticonControl), new PropertyMetadata(null));



        public bool ShowEmoticonPanel
        {
            get { return (bool)GetValue(ShowEmoticonPanelProperty); }
            set { SetValue(ShowEmoticonPanelProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ShowEmoticonPanel.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ShowEmoticonPanelProperty =
            DependencyProperty.Register("ShowEmoticonPanel", typeof(bool), typeof(EmoticonControl), new PropertyMetadata(false));//, new PropertyChangedCallback(ShowEmoticonPanelProperty_Callback)));


        public EmoticonControl()
        {
            InitializeComponent();
            //this.DefaultEmoticonsListBox.DataContext = this;
            //this.CustomEmoticonsListBox.DataContext = this;
            //this.RecentlyUsedEmoticonsListBox.DataContext = this;
            this.EmoticonGrid.DataContext = this;
            //if (DesignerProperties.IsInDesignTool)
            //    return;
            DateTime start = DateTime.Now;
            //RecentlyUsedEmoticons = new ObservableCollection<EmoticonModel>();
            DeleteCustomEmoticonCommand = new RelayCommand<EmoticonModel>(DeleteEmoticon);
            Debug.WriteLine("Time to open emoticonsControl: " + DateTime.Now.Subtract(start).TotalMilliseconds);

        }

        private static void IsTouchSensitiveProperty_Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            bool newValue = (bool)e.NewValue;
            bool oldValue = (bool)e.OldValue;
            EmoticonControl ec = d as EmoticonControl;
            if (e.OldValue == null || newValue != oldValue)
            {
                if (newValue == true)
                {
                    Touch.FrameReported += new TouchFrameEventHandler(ec.Touch_FrameReported);
                }
                else
                {
                    Touch.FrameReported -= new TouchFrameEventHandler(ec.Touch_FrameReported);
                }
            }

        }
        private void DeleteEmoticon(EmoticonModel model)
        {
            this.CustomEmoticons.Remove(model);
        }


        void Touch_FrameReported(object sender, TouchFrameEventArgs e)
        {
            TouchPoint ppoint = e.GetPrimaryTouchPoint(null);

            if (ppoint != null)
            {
                var elements = VisualTreeHelper.FindElementsInHostCoordinates(ppoint.Position, this);

                Button b = elements.FirstOrDefault(x => x.GetType() == typeof(Button)) as Button;
                if (b == null)
                    return;
                switch (ppoint.Action)
                {
                    case TouchAction.Up:
                        {
                            if (b == BackspaceButton)
                            {
                                if (BackspaceEvent != null)
                                {
                                    BackspaceEvent(this, null);
                                }
                            }
                            else if (b == SendButton)
                            {
                                if (SendMessageEvent != null)
                                {
                                    SendMessageEvent(this, null);
                                }
                            }
                            break;
                        }
                }
            }
        }

        private void BackspaceButton_Hold(object sender, System.Windows.Input.GestureEventArgs e)
        {
            isHolding = true;
            HoldingThread = new Thread(() =>
            {
                DateTime start = DateTime.UtcNow;
                while (isHolding)
                {
                    this.Dispatcher.BeginInvoke(() =>
                        {
                            if (BackspaceEvent != null)
                                BackspaceEvent(this, null);
                        });
                    int sleeptime = 100;
                    if (DateTime.UtcNow.Subtract(start).TotalSeconds >= 1.5)
                        sleeptime = 50;
                    Thread.Sleep(sleeptime);

                }
            });
            HoldingThread.Start();
        }
        private void BackspaceButton_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            isHolding = false;
        }

        private void EmoticonPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (DesignerProperties.IsInDesignTool)
                return;
            AppSettings.AppSettingsInstance.LastOpenedEmoticonPageIndex = this.EmoticonPivot.SelectedIndex;
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (DesignerProperties.IsInDesignTool)
                return;

            this.EmoticonPivot.SelectedIndex = AppSettings.AppSettingsInstance.LastOpenedEmoticonPageIndex; ;


        }

        private void EmoticonButton_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            Button b = sender as Button;
            EmoticonModel model = b.DataContext as EmoticonModel;

            if (ClickEmoticonEvent != null)
                ClickEmoticonEvent(this, new EmoticonClickedEventArgs(model));
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
}
